<?php
namespace App\Admin\Controllers\SalesReport;

use App\Logic\MonthlyReport\CheckLogisticsAvgPrice;
use App\Logic\MonthlyReport\ParseMiss;
use App\Models\Basics\SysArea;
use App\Models\Basics\SysPlat;
use App\Models\CustomerDelivery\CustomerDelivery;
use App\Models\Delivery\FBADelivery;
use App\Models\MonthlyReport\Cost\LogisticsBasics;
use App\Models\MonthlyReportCommon\Cost\PriceBasics;
use App\Models\OverSeasIn\Delivery as OSDelivery;
use App\Models\OverSeasOut\FBADelivery as OSFBADelivery;
use App\Models\OverSeasOut\RemovaleDelivery;
use App\Models\Product\ProductSku;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;
class ManualController extends AdminController{

    protected $title = '月报核算说明';

    protected function grid()
    {
        return view('sales-report.payment-manual.index');
    }

    public function purPriceDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="采购成本.csv"',
        ]);
        $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
        $_date = date('Y-m-01',strtotime('midnight first day of -3 month'));
        $query = PriceBasics::query()->where('b_date','>=',$_date)->where('b_date','<=',$date);
        $response->setCallback(function () use ($query) {
            $head = ['日期', 'SKU ID', 'SKU', '销量', '成本'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->orderBy('id')->chunk(100, function ($re) use ($fp){
                $data = self::_getPurPriceData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getPurPriceData($re): \Generator
    {
        $sku = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            $temp = [
                $row->b_date,
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity,
                $row->price
            ];
            yield $temp;
        }
    }

    public function logisticsAvgPriceDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="运费平均价格核算状态.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, ['类型', '订单号', '说明', 'SKU']);
            //FBADelivery
            FBADelivery::query()
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                $data = self::_getLogisticsAvgPriceData($re,'国内发FBA');
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            //OSDelivery
            OSDelivery::query()
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsAvgPriceData($re,'海外仓中转-入仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //OSFBADelivery
            OSFBADelivery::query()
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsAvgPriceData($re,'海外仓中转-出仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //RemovaleDelivery
            RemovaleDelivery::query()
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsAvgPriceData($re,'海外仓移库-出仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //CustomerDelivery
            CustomerDelivery::query()
                ->where('logistics_check_status','<>',0)
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsAvgPriceData($re,'客户订单发货出仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsAvgPriceData($re,$type): \Generator
    {
        foreach ($re as $row){
            $temp = [
                $type,
                $row->delivery_no,
                CheckLogisticsAvgPrice::$_logisticsCheckStatus[$row->logistics_check_status],
                '',
            ];
            yield $temp;
            foreach ($row->detail as $item){
                $temp = [
                    '',
                    '',
                    '',
                    ProductSku::getValueById($item->psku_id,'psku_code'),
                ];
                yield $temp;
            }
        }
    }

    public function logisticsBalanceDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="未纳入运费系统的订单.csv"',
        ]);
        $response->setCallback(function (){
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, ['类型', '订单号']);
            //FBADelivery
            FBADelivery::query()
                ->where('status',6)//已发货
                ->where('logistics_status',2)//运费已更新
                ->where('logistics_fee_status',0)//未纳入统计
                ->where('logistics_check_status',0)//运费核算状态正常
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsBalanceData($re,'FBA');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //OSDelivery(amazon)
            OSDelivery::query()
                ->where('plat_id',SysPlat::PLAT_AMAZON)
                ->where('status','>=',6)//已发货或已入海外仓中转仓
                ->where('logistics_status',2)//运费已更新
                ->where('logistics_fee_status',0)//未纳入统计
                ->where('logistics_check_status',0)//运费核算状态正常
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsBalanceData($re,'海外仓中转加代发-入仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //OSFBADelivery
            OSFBADelivery::query()
                ->where('status',3)//已发货
                ->where('logistics_status',2)//运费已更新
                ->where('logistics_fee_status',0)//未纳入统计
                ->where('logistics_check_status',0)//运费核算状态正常
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsBalanceData($re,'海外仓中转-出仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            //RemovaleDelivery
            RemovaleDelivery::query()
                ->where('status',4)//已发货
                ->where('logistics_status',2)//运费已更新
                ->where('logistics_fee_status',0)//未纳入统计
                ->where('logistics_check_status',0)//运费核算状态正常
                ->orderBy('id')
                ->chunk(100, function ($re) use ($fp){
                    $data = self::_getLogisticsBalanceData($re,'海外仓移库-出仓');
                    foreach ($data as $item) {
                        fputcsv($fp, $item);
                    }
                });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsBalanceData($re,$type): \Generator
    {
        foreach ($re as $row){
            $temp = [
                $type,
                $row->delivery_no,
            ];
            yield $temp;
        }
    }

    public function logisticsBasicsDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="物流成本.csv"',
        ]);
        $date = date('Y-m-01',strtotime('midnight first day of -1 month'));
        $_date = date('Y-m-01',strtotime('midnight first day of -3 month'));
        $query = LogisticsBasics::query()->where('b_date','>=',$_date)->where('b_date','<=',$date);
        $response->setCallback(function () use ($query) {
            $head = ['日期', '站点ID', '站点', 'SKU ID', 'SKU', '销量', '成本'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->orderBy('id')->chunk(100, function ($re) use ($fp){
                $data = self::_getLogisticsBasicsData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getLogisticsBasicsData($re): \Generator
    {
        $sku = [];
        $area = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$sku)){
                $sku[$row->psku_id] = ProductSku::getValueById($row->psku_id,'psku_code');
            }
            if(!array_key_exists($row->area_id,$area)){
                $sku[$row->area_id] = SysArea::getSysAreaById($row->area_id);
            }
            $temp = [
                $row->b_date,
                $row->area_id,
                $sku[$row->area_id],
                $row->psku_id,
                $sku[$row->psku_id],
                $row->quantity,
                $row->price
            ];
            yield $temp;
        }
    }

    public function missSkuDownload(){
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="排查出的未上传的SKU.csv"',
        ]);
        $query = DB::table('mr_parse_miss');
        $response->setCallback(function () use ($query) {
            $head = ['国家','平台SKU','问题描述','源文件','时间'];
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->orderBy('id')->chunk(100, function ($re) use ($fp){
                $data = self::_getMissSkuData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private static function _getMissSkuData($re): \Generator
    {
        foreach ($re as $row){
            $temp = [];
            $temp['country'] = $row->country;
            $temp['sku'] = $row->sku;
            $temp['desc'] = $row->desc;
            $temp['sour'] = array_key_exists($row->sour,ParseMiss::$_file) ? ParseMiss::$_file[$row->sour] : $row->sour;
            $temp['created_at'] = $row->created_at;
            yield $temp;
        }
    }

}
